package gri_meta_report_config;

use xml_helper;
use File::Basename;
use Data::Dumper;
use Cwd;

my $error="";

# validate_xml is actually a class sub rather than instance sub

sub validate_xml {
my $xml=shift;

	new("",undef,$xml);
	if($error eq "") {
		return undef;
	}
	return $error;
}

sub new {
my $self={};
shift;
my $f=shift;

	$self->{xml_helper}=new xml_helper();

	$error="";
	my $d=""; my $fd;
	if(defined($f)) {
		if(!open($fd,$f)) {
			$error="Can not open file '$f' : $!";
			return(undef);
		}
		$d=join("",<$fd>);
		close($fd);
		my $fn=basename($f); $fn =~ s/\.xml$//;
		$self->{filename}=$fn;
	} else {
		$d=shift;
	}
	my $x=$self->{xml_helper}->parse($d);
	$x=$self->{raw_xml}=$d;
	if(! $x) {
		$error="Unable to parse XML!";
		return undef;
	}

	# Check the data is in the format we expect.

	my ($data,$attrs,$elements)=$self->{xml_helper}->get_element("");
	if(!defined($data)) {
		$error="Invalid data to parse [top level]";
		return(undef);
	}
	if(scalar(@$elements)!=1) {
		$error="More than 1 top level element!";
		return(undef);
	}
	if($elements->[0] ne "meta-report") {
		$error="Top level element is not 'meta-report'";
	}
	($data,$attrs,$elements)=$self->{xml_helper}->get_element("meta-report#0");
	if(!defined($data)) {
		$error="Invalid data to parse [meta-report#0]";
		return(undef);
	}
	#################################################################
	# We expect the title and reports elements to be here - abort	#
	# if not.							#
	#################################################################
	if(! grep {$_ eq "meta-report#0|title#0"} @$elements) {
		$error="Missing 'title' element.";
		return(undef);
	}
	if(! grep {$_ eq "meta-report#0|report#0"} @$elements) {
		$error="A meta-report must contain at least one 'report' element.";
		return(undef);
	}
	if(! grep {$_ eq "meta-report#0|meta-info#0"} @$elements) {
		$error="Missing 'meta-info' element.";
		return(undef);
	}
	for my $cent (@$elements) {
		if(! grep {$_ eq $cent} (
			"meta-report#0|title#0",
			"meta-report#0|report#0",
			"meta-report#0|meta-info#0",
			"meta-report#0|attributes#0")) {
			$error="Unexpected element '$cent' found.";
			return(undef);
		}
	}
	#################################################################
	# Get the data and store in the object for easy reference.	#
	#################################################################
	my ($data2,$attrs2,$elements2)=$self->{xml_helper}->get_element("meta-report#0|title#0");
	$self->{title}=$data2;

	#################################################################
	# Capture each instance of the defined reports...		#
	#################################################################
	my $ll=0;
	my @reports=();
	while(1) {
		my ($data2,$attrs2,$elements2)=$self->{xml_helper}->get_element("meta-report#0|report#$ll");
		last if !defined($data2);
		my %crep=();
		for my $cel (@$elements2) {
			my ($data3,$attrs3,$elements3)=$self->{xml_helper}->get_element($cel);
			my @F=split(/\|/,$cel);
			my $cel2=$F[$#F];
			$cel2 =~ s/#\d+$//;
			if(! grep {$_ eq $cel2} ("host","type","name","directory")) {
				$error="Unexpected element '$cel2' found in report element.";
				return(undef);
			}
			$crep{$cel2}=$data3;
		}
		push @reports,{%crep};
		$ll++;
	}
	$self->{reports}=[@reports];

	# Gather information for the meta-info
	# content_type,type, sort, count, chart_hints (for content_type==chart) for the moment
	($data2,$attrs2,$elements2)=$self->{xml_helper}->get_element("meta-report#0|meta-info#0");

	$self->{metainfo}={};
	for my $cel (@$elements2) {
		my ($data3,$attrs3,$elements3)=$self->{xml_helper}->get_element($cel);
		my @F=split(/\|/,$cel);
		my $cel2=$F[$#F];
		$cel2 =~ s/#\d+$//;
		if(! grep {$_ eq $cel2} ("content_type","type","group_by","sort","count","chart_hints","content_format")) {
			$error="Unexpected element '$cel2' found in meta-info element.";
			return(undef);
		}
		$self->{metainfo}->{$cel2}=$data3;
	}
	bless($self);
	return $self;
}

sub get_title {
my $self=shift;
	return $self->{title};
}

sub get_attributes {
my $self=shift;
	return $self->{attributes};
}

sub get_report_count {
my $self=shift;
	return scalar(@{$self->{reports}});
}

# If optional raw=>1 is present then do not convert the %INST% to the 
# current directory before returning the results...

sub get_report_info($$) {
my $self=shift;
my $cn=shift;
my %args=@_;

	if(exists($args{raw}) && $args{raw}) {
		return $self->{reports}->[$cn];
	}

	my $x=$self->{reports}->[$cn]->{directory};
	my $y=getcwd;
	
	$x =~ s/^\%INST\%[\/]{0,}/$y\//;
	my %z=%{$self->{reports}->[$cn]};
	$z{directory}=$x;
	return {%z};
}

# If optional raw=>1 is present then do not convert the %INST% to the 
# current directory before returning the results...

sub get_name_and_directory($$) {
my $self=shift;
my $cn=shift;
my %args=@_;

	my $x=$self->{reports}->[$cn]->{directory};
	if(!exists($args{raw}) || !$args{raw}) {
		my $y=getcwd;
		$x =~ s/^\%INST\%[\/]{0,}/$y\//;
	}
	return ($self->{reports}->[$cn]->{name},$x);
}

sub get_type {
my $self=shift;
my $cn=shift;

	if(!defined($self->{reports}->[$cn]->{type}) || $self->{reports}->[$cn]->{type} eq "") {
		return "html";
	}
	return $self->{reports}->[$cn]->{type};
}

sub get_meta_info {
my $self=shift;

	return $self->{metainfo};
}

sub get_details2 {
my $self=shift;

	my %H=();
	my @h2=();
	# Work out a list of hosts first...
	for my $cr (@{$self->{reports}}) {
		$H{$cr->{host}}=1;
		push @h2,$cr->{host} . ":" . $cr->{name};
	}
	# Name is usually the pattern of the filename - here we
	# build up a long string just in case in the format:
	# host:pattern|...

	
	return {
		title => $self->{title},
		host => join(",",sort(keys(%H))),
		directory => "NA - Meta Report",
		type => $self->{metainfo}->{content_type} . "/" . $self->{metainfo}->{type},
		reptype => 'M',
		paging => "NA - Meta Report",
		attributes => $self->{attributes},
		display_name => "NA - Meta Report",
		dynamic_convert_args => "NA - Meta Report",
		dynamic_convert_type => "NA - Meta Report",
		dynamic_convert_desc => "NA - Meta Report",
		name => join("|",@h2),
		filename => $self->{filename},
	};
}

sub error {
	return $error;
}

sub get_xml {
my $self=shift;

	return $self->{raw_xml};
}

1;

